package com.nassir.excel;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import com.nassir.excel.cellwriter.DefaultCellWriter;
import com.nassir.excel.cellwriter.ICellWriter;
import com.nassir.excel.model.Cell;
import com.nassir.excel.model.ExcelModel;
import com.nassir.excel.model.Sheet;
import com.nassir.excel.model.SheetModel;
import com.nassir.excel.model.WorkBook;
import com.nassir.xml.xmlreader.XmlReader;


/**
 * 
 * @author zhangqiulong
 *
 */
@SuppressWarnings("unchecked")
public class ExcelWriter{
	
    private OutputStream out = null;
    private HSSFWorkbook hssfworkbook = null;
    

    
    public ExcelWriter(OutputStream out) {
        this.out = out;
        this.hssfworkbook = new HSSFWorkbook();

    }

	public  void write(ExcelModel exclMode) throws FileNotFoundException, Exception
    {
        XmlReader xmlReader=null;
        xmlReader=new XmlReader(exclMode.getFile());
        if(null != exclMode.getFile()){
            if(null==exclMode.getFileName() || "".equals(exclMode.getFileName())){
                throw new IllegalArgumentException("fileName为空！需指定生成配置的file！");
            }
            List<Sheet> xmlSheetList=xmlReader.getFile(exclMode.getFileName()).getSheets();
            for (Sheet sheet : xmlSheetList) {
                
                HSSFSheet hssfsheet = hssfworkbook.createSheet(sheet.getName());
                Object[] cells=sheet.getCells().toArray();
                this.creatHead(hssfsheet, cells);
                
                //获取当前sheet页的数据
                SheetModel sheetModel=exclMode.getSheetModel(sheet.getName());
                if(null !=sheetModel)
                {
                    List<Object []> dataList=sheetModel.getSheetRows();
                    this.creatRows(hssfsheet, dataList,cells,xmlReader.getWorkbook());
                }
                
            }
        }
        else{
            for (SheetModel sheetModel2 : exclMode.getSheetModels()) {
                HSSFSheet hssfsheet = hssfworkbook.createSheet(sheetModel2.getSheetName());
                this.creatHead(hssfsheet, sheetModel2.getSheetHead());
                
                //获取当前sheet页的数据
                List<Object []> dataList=sheetModel2.getSheetRows();
                this.creatRows(hssfsheet, dataList,sheetModel2.getSheetHead(),xmlReader.getWorkbook());
            }
        }
       hssfworkbook.write(out); 
       out.close();
    }
	
	/**
	 * 创建数据
	 * @param hssfsheet
	 * @param dataList
	 */
    public  void creatRows(HSSFSheet hssfsheet, List<Object []> dataList,Object [] headCells,WorkBook workBook)
    {
    	if(null !=dataList && !dataList.isEmpty()){
	    	int i=1;
	    	for (Object[] objects : dataList) {
	    		HSSFRow headrow = hssfsheet.createRow(i);
	    		this.creatRow(headrow, objects,headCells,workBook);
	    		i++;
				
			}
    	}
    	      
    }
    

	
    /**
     * 创建一行数据
     *  type ：1为创建head，2为创建数据 
     * @param currentRow
     * @param cells
     */
    public  void creatRow(HSSFRow currentRow, Object [] cells,Object [] headCells,WorkBook workBook)
    {
    	
        if (cells != null && cells.length > 0){
            int i = 0;
            for (Object cel : cells){
                HSSFCell hssCell = currentRow.createCell(i);
                HSSFCellStyle cellStyle=hssfworkbook.createCellStyle();
                
                //设置单元格数据对齐方式 HSSFCellStyle.ALIGN_CENTER
                cellStyle.setAlignment((short)0);  
                //设置配置的宽度不够自动换行
                cellStyle.setWrapText(true);   
                hssCell.setCellStyle(cellStyle);
                this.setCellValue(hssCell,cel,headCells[i],workBook);
                
                
                i++;
            }
            
        }
        //HSSFCell.CELL_TYPE_STRING
    }
    
    /**
     * 创建一行数据
     *  type ：1为创建head，2为创建数据 
     * @param currentRow
     * @param cells
     */
    public  void creatHead(HSSFSheet hssfsheet, Object [] cells)
    {
    	//hssfsheet.autoSizeColumn(( short ) 0 );
    	HSSFRow currentRow=hssfsheet.createRow(0); 
        if (cells != null && cells.length > 0){
            int i = 0;
            for (Object cel : cells){
            	
                HSSFCell hssCell = currentRow.createCell(i);       
                HSSFCellStyle cellStyle=hssfworkbook.createCellStyle();  
                cellStyle.setWrapText(true);   
                hssCell.setCellStyle(cellStyle);
                
            	if(cel instanceof String){
            		hssCell.setCellValue(cel.toString());
            	}
            	else if( cel instanceof Cell){
            		Cell cell=(Cell) cel;
            		if(null != cell.getWidth()&& !"".equals(cell.getWidth())){
            			hssfsheet.setColumnWidth(i, Integer.parseInt(cell.getWidth())* 256);
            		}
            		
               	 	hssCell.setCellValue(cell.getTitle());
            	} 
            	i++;
            }
            
        }
        //HSSFCell.CELL_TYPE_STRING
    }
    
 
    
    
    public  void setCellValue(HSSFCell cell,Object celObj,Object headCell,WorkBook workBook) {
    	
    	if(headCell instanceof Cell){
        	Cell cellcur=(Cell) headCell;
        	if(null !=cellcur.getType() || null !=cellcur.getFormat()){
        		if(null ==cellcur.getType() ){
        			throw new IllegalArgumentException(cellcur.getTitle() +" 需指定type格式化类型！");
        		}
        		if(null ==cellcur.getFormat() ){
        			throw new IllegalArgumentException(cellcur.getTitle() +" 需指定format格式！");
        		}
        	 }

        	
        	Map<String,ICellWriter<Object>> cellwriter=workBook.getCellwriter();
        	ICellWriter<Object> foundCellWriter=null;
        	if(null !=cellcur.getType() && !"".equals(cellcur.getType()))
        	{
        		try{
        			//foundCellWriter = (ICellWriter) Class.forName(cellcur.getType()).newInstance();
        			foundCellWriter=cellwriter.get(cellcur.getType());
		        	if (foundCellWriter == null) {
		    			throw new RuntimeException("not found cell writer for type:" + cellcur.getFormat());
		    		}
        		}catch(Exception e)
        		{
        			throw new RuntimeException("Load Custom cell writer for type:" + cellcur.getFormat()+" Failure");
        		}
        	}
        	else
        	{
        		foundCellWriter=new DefaultCellWriter();
        	}
        	
        	foundCellWriter.write(cell, cellcur, celObj);
        	
        	
        	/*ICellWriter foundCellWriter = null;
        	for (ICellWriter cellWriter : cellcur.getCellWriters()) {
        		if (cellWriter.accept(cellcur.getType())) {
        			foundCellWriter = cellWriter;
        		}
        	}
        	
        	if (foundCellWriter != null) {
        		foundCellWriter.write(cell, cellcur, celObj);
    		} else {
    			throw new RuntimeException("not found cell writer for type:" + cellcur.getFormat());
    		}*/
        	
        	/*if("date".equals(cellcur.getType())){
        		Date dateval=(Date) celObj;
        		 // cell.setEncoding(XLS_ENCODING);
        	    cell.setCellValue(dateval);
    	        HSSFCellStyle cellStyle = hssfworkbook.createCellStyle(); 
    	        cellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat(cellcur.getFormat())); 
    	        cell.setCellStyle(cellStyle);
    	        
        	}
        	if("double".equals(cellcur.getType())){
        		 double data=Double.valueOf( celObj.toString());
        		 cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
        	     cell.setCellValue(data);
        	     
        	     
    	        HSSFCellStyle cellStyle = this.hssfworkbook.createCellStyle(); 
    	        HSSFDataFormat dataformat = this.hssfworkbook.createDataFormat();
    	        cellStyle.setDataFormat(dataformat.getFormat(cellcur.getFormat())); 
    	        cell.setCellStyle(cellStyle); 
        		
        	}*/
        	
        	/*if(null==cellcur.getType() || "".equals(cellcur.getType())){       		
        		if(celObj instanceof String ){
        			cell.setCellType(HSSFCell.CELL_TYPE_STRING);
            		cell.setCellValue(celObj.toString());
            	}
            	else if(celObj instanceof Boolean ){
            		cell.setCellType(HSSFCell.CELL_TYPE_BOOLEAN);
            		cell.setCellValue(Boolean.valueOf(celObj.toString()));
            	}
            	else{
            		cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
            		cell.setCellValue(Double.valueOf( celObj.toString()));
            	}
        		
           }*/
        }
    	else{
    		cell.setCellValue(celObj.toString());
    	}
       
    }
	
	public static void main(String[] args) throws Exception {
		List<SheetModel> modelList=new ArrayList<SheetModel>();
		SheetModel sheetModel=new SheetModel();
		sheetModel.setSheetName("add-on");
		List<Object []> sheet2=new ArrayList<Object[]>();
		sheet2.add(new Object []{new Date(),2.0,"3","3","3","3","3","3","3","3","3","3",3});
		sheet2.add(new Object []{new Date(),5.1,"1988-02-20 8:20:03","3","3","3","3","3","3","3","3","3",3});
		sheetModel.setSheetRows(sheet2);
		modelList.add(sheetModel);
		//end预置数据
		ExcelWriter ew2=new ExcelWriter(new FileOutputStream("test.xls"));
		String path="src/workbook-config.xml";
		System.out.println(path);
		java.io.File file1=new java.io.File(path);
        ExcelModel m=new ExcelModel(file1,"account",modelList);
		ew2.write(m);
		
		/*//第一种
		//start预置数据
		List<SheetModel> modelList=new ArrayList<SheetModel>();
		SheetModel sheetModel=new SheetModel();
		sheetModel.setSheetName("add-on");
		
		List<Object []> sheet2=new ArrayList<Object[]>();
		sheet2.add(new Object []{new Date(),2.0,"3","3","3","3","3","3","3","3","3","3",3});
		sheet2.add(new Object []{new Date(),5.1,"1988-02-20 8:20:03","3","3","3","3","3","3","3","3","3",3});
		sheetModel.setSheetRows(sheet2);
		modelList.add(sheetModel);
		//end预置数据
		ExcelWriter ew2=new ExcelWriter(new FileOutputStream("D:/国际TTS系统运价政策(xmlhead).xls"));
		ExcelModel m=new ExcelModel();
		m.setFile(new java.io.File(ExcelWriter.class.getResource("").getPath()+"/conf/workbookconfig.xml"));
		m.setFileName("国际TTS系统运价政策");
		m.setSheetModels(modelList);
		ew2.write(m);*/
		
		
		
		//第二种
		
		/*//start预置数据
		List<SheetModel> modelList=new ArrayList<SheetModel>();
		SheetModel sheetModel=new SheetModel();		
		sheetModel.setSheetName("add-on");
		sheetModel.setSheetHead(new Object []{"tit1","tit2","tit3","tit4","tit5","tit6","tit7","tit8","tit9"});

		List<Object []> sheet2=new ArrayList<Object[]>();
		sheet2.add(new Object []{"1","2","3","3","3","3","3","3","3"});
		sheet2.add(new Object []{4,"5","6","3","3","3","3","3","3"});
		sheetModel.setSheetRows(sheet2);
		
		modelList.add(sheetModel);
		
		
		SheetModel sheetModel2=new SheetModel();
		sheetModel2.setSheetName("舱位");
		modelList.add(sheetModel2);
		//end预置数据
		
		ExcelWriter ew2=new ExcelWriter(new FileOutputStream("D:/国际TTS系统运价政策(自定义head).xls"));
		ExcelModel m=new ExcelModel();
		m.setSheetModels(modelList);
		ew2.write(m);*/

		System.out.println("完...");
	}
	
	

}
